<?php
/**
 * Smarty模板适配库.
 * 
 * 
 * smarty模板包装函数,添加插件扩展机制
 * 
 * @author Leo Ning <leo.ning@like18.com>
 * @copyright LIKE18 INC. 2008 - 2011
 * @version 1.0
 * @since 1.0
 * @package core
 * @subpackage template
 */
/**
 * Smarty实例
 *
 * 用于清空Smarty模板缓存.
 *
 * @global Smarty
 * @name $__csmarty
 * @var Smarty
 */
$__csmarty = null;
/**
 * smarty模板
 *
 * @global string
 * @name $__smarty_tpl
 * @var string
 */
$__smarty_tpl = null;
/**
 * 开启模板输出.
 *
 * 它会判断模板是否已经缓存,如果缓存了则直接输出缓存的内容
 * 如果是同一模板有不同的缓存,请使用$cacheid要区分
 *
 * @global Smarty Smarty模板引擎
 * @global string Smarty模板文件
 * @uses apply_filter 触发init_smarty_engine过滤器,以smarty添加插件扩展
 * @uses KickAss 管理内容输出
 * @param string $tpl
 * 模板文件
 * @param int $expire
 * 缓存时间
 * @param string $cacheid
 * 缓存 ID,默认为null,不缓存.
 */
function tpl_start($tpl, $expire = 3600, $cacheid = null) {
	global $__smarty, $__smarty_tpl;
	Response::begin ( request_uri () );
	$cacheid = $cacheid == null ? md5 ( request_uri () ) : md5 ( $cacheid );
	if ($__smarty == null) {
		$__smarty = new Smarty ();
		$__smarty->use_sub_dirs = false;
		$__smarty->addPluginsDir ( CORE_PLUGIN_PATH . 'smarty' );
	}
	$subdir = str_replace ( DS, '/', dirname ( $tpl ) );
	$__smarty->template_dir = TEMPLATE_PATH; // 模板目录
	$__smarty->compile_dir = TMP_PATH . 'tpls_c' . DS . 'templates' . DS . $subdir; // 模板编译目录
	$__smarty->cache_dir = TMP_PATH . 'tpls_cache' . DS . 'templates' . DS . $subdir; // 模板缓存目录
	$__smarty->_dir_perms = 0775;
	if (DEBUG) {
		$this->__smarty->force_compile = true;
	}
	$expire = intval ( $expire );
	if ($expire > 0) {
		$this->__smarty->setCaching ( Smarty::CACHING_LIFETIME_CURRENT );
		$this->__smarty->setCacheLifetime ( $expire );
	}
	if (! empty ( $cacheid )) {
		$__smarty->cache_id = $cacheid;
	}
	$__smarty = apply_filter ( 'init_smarty_engine', $__smarty );
	$__smarty_tpl = $tpl;
	if ($__smarty->isCached ( $tpl )) {
		$content = $__smarty->fetch ( $tpl );
		echo $content;
		Response::close ();
	}
}

/**
 * 输出模板内容.
 *
 * 根据tpl_start中设置的模板,缓存,$cacheid等信息,使用$data中数据,输出模板内容.
 *
 * @global Smarty Smarty模板引擎
 * @global string Smarty模板文件
 * @param array $data
 * 要传给模板的数据
 */
function tpl_end_display($data) {
	global $__smarty, $__smarty_tpl, $__global;
	if ($__smarty == null) {
		elog ( 'the smarty engine is not defined,please use tpl_start function to begin a smarty engine' );
	}
	$data = array_merge ( $__global, $data );
	foreach ( $data as $name => $value ) {
		$__smarty->assign ( $name, $value );
	}
	$content = $__smarty->fetch ( $__smarty_tpl );
	echo $content;
}
/**
 * 清空全部缓存
 *
 * @global Smarty Smarty模板引擎
 * @param int $expire
 * 缓存时间
 */
function tpl_clear_all_cache($expire = null) {
	global $__csmarty;
	if ($__csmarty == null) {
		$__csmarty = new Smarty ();
		$__csmarty->compile_dir = TMP_PATH . 'tpls_c'; // 模板编译目录
		$__csmarty->cache_dir = TMP_PATH . 'tpls_cache'; // 模板缓存目录
	}
	return $__csmarty->clearAllCache ( $expire );
}
/**
 * 取当前smarty对应的编译器
 *
 * 此方法只在Smarty模板插件中有效,其它时间均返回false.
 *
 * @param Smarty $smarty
 * 模板引擎
 * @return compiler_object 模板引擎对象实例
 */
function get_smarty_compiler($smarty) {
	if (isset ( $smarty->parser )) {
		return $smarty->parser->compiler;
	} else if (isset ( $smarty->template_objects ) && ! empty ( $smarty->template_objects )) {
		$tpl = trim ( str_replace ( $smarty->template_dir, '', $smarty->_current_file ), DS );
		if (DS != '/') {
			$tpl = str_replace ( DS, '/', $tpl );
		}
		foreach ( $smarty->template_objects as $c ) {
			if ($c->template_resource == $tpl) {
				return $c->compiler ? $c->compiler : $c->compiler_object;
			}
		}
	}
	return null;
}
/**
 * 解析smarty参数.
 *
 * 将参数中 '" 去除比,如 '1' 转换为1.
 *
 * @param array $args
 * 参数数组
 * @return array 解析后的参数
 */
function smarty_parse_args($args) {
	foreach ( $args as $key => $value ) {
		if (strpos ( $value, '_smarty_tpl->tpl_vars' ) !== false) {
			$args [$key] = trim ( $value, '\'"' );
		}
	}
	return $args;
}
/**
 *
 *
 * 将smarty传过来的参数转换为可eval的字符串
 * 
 * @param array $args        	
 * @return string
 */
function smarty_argstr($args) {
	$a = array ();
	foreach ( $args as $k => $v ) {
		$v1 = trim ( $v );
		if (empty ( $v1 )) {
			continue;
		}
		$a [] = "'$k'=>$v";
	}
	return 'array(' . implode ( ',', $a ) . ')';
}
/**
 * 
 * 输入安全URL
 * @param string $url
 * @return string
 */
function the_safe_url($page) {
	global $_PAGE;
	static $domain = false, $proto = false, $port = '';
	if (! $domain) {
		$domain = preg_match ( '#^https?://#i', BASE_URL ) ? preg_replace ( '#^https?://#i', '', trim ( BASE_URL, '/' ) ) : $_SERVER ['HTTP_HOST'];
		$domain = strstr ( $domain, "." );
		$proto = isset ( $_SERVER ['HTTPS'] ) ? 'https://' : 'http://';
		$port = intval ( $_SERVER ['SERVER_PORT'] ) == 80 ? '' : ':' . $_SERVER ['SERVER_PORT'];
	}
	if (is_string ( $page )) {
		$url = $page;
		$page = $_PAGE;
	} else {
		$url = $page ['url'];
	}
	if (preg_match ( '/index\.html?$/i', $url )) {
		$url = preg_replace ( '/index\.html?$/i', '', $url );
	}
	if (preg_match ( '#^(http|ftp)s?://#i', $url )) {
		return $url;
	} else {
		$url = ltrim ( $url, '/' );
		if (isset ( $page ['bind'] ) && ! empty ( $page ['bind'] )) { //绑定了二级域名
			if (! empty ( $page ['domain_home'] ) || ! empty ( $page ['home'] )) { //是二级域名的首页啦，要清空url
				$url = '';
			}
			return $proto . $page ['bind'] . $domain . $port . '/' . $url;
		} else {
			return BASE_URL . $url;
		}
	}
}
/**
 * Smarty here modifier plugin
 *
 * <code>
 * {'images/logo.png'|here}
 * </code>
 * 以上代表输出模板所在目录下的images/logo.png
 *
 * Type: modifier<br>
 * Name: here<br>
 * Purpose: 输出模板所在目录下资源的URL
 *
 * @staticvar string WEBROOT的LINUX表示.
 * @param array $params
 * 参数
 * @param Smarty $compiler        	
 * @return string with compiled code
 */
function smarty_modifiercompiler_here($params, $compiler) {
	global $__global;
	static $base = null, $mod = null;
	if ($base == null) {
		$base = str_replace ( DS, '/', WWW_ROOT );
	}
	if ($mod == null) {
		if ($__global ['is_plugin_action']) {
			$mod = str_replace ( DS, '/', PLUGIN_PATH );
		} else {
			$mod = str_replace ( DS, '/', MODULE_PATH );
		}
	}
	if (! defined ( 'HERE_DIR' )) {
		$tpl = str_replace ( DS, '/', dirname ( $compiler->template->source->filepath ) );
		if (strpos ( $tpl, $base ) === 0) {
			$tpl = str_replace ( $base, '', $tpl );
		} else {
			$tpl = str_replace ( $mod, '', $tpl );
			if ($__global ['is_plugin_action']) {
				$tpl = 'plugins/' . $tpl;
			}
			if (preg_match ( '#^default/' . VIEW_DIR . '.*#', $tpl )) {
				$tpl = '';
			} else {
				$tpl = preg_replace ( '#' . VIEW_DIR . '/?#', '', $tpl );
			}
		}
	} else {
		$tpl = HERE_DIR;
	}
	$url = (! empty ( $tpl ) ? trailingslashit ( $tpl ) : '');
	return "the_safe_url('{$url}')." . $params [0];
}
function smarty_modifiercompiler_shared($params, $compiler) {
	$tpl = defined ( 'SHARED_DIR' ) ? SHARED_DIR : 'shared';
	$url = (! empty ( $tpl ) ? trailingslashit ( $tpl ) : '');
	return "BASE_URL.'{$url}'." . $params [0];
}
/**
 * 
 * 输出绝对引用
 * @param array $params
 * @param unknown_type $compiler
 */
function smarty_modifiercompiler_base($params, $compiler) {
	return "BASE_URL." . $params [0];
}
/**
 * 
 * 输出URL
 * @param unknown_type $params
 * @param unknown_type $compiler
 */
function smarty_modifiercompiler_url($params, $compiler) {
	$page = array_shift ( $params );
	$args = empty ( $params ) ? array () : smarty_argstr ( $params );
	if (! empty ( $args )) {
		$output = "build_page_url(the_safe_url({$page}),$args)";
	} else {
		$output = "the_safe_url({$page})";
	}
	return $output;
}
/**
 * 
 * 引用jquery资源
 * @param unknown_type $params
 * @param unknown_type $compiler
 */
function smarty_modifiercompiler_jquery($params, $compiler) {
	$tpl = defined ( 'SHARED_DIR' ) ? SHARED_DIR : 'shared';
	$tpl .= "/jquery";
	$url = (! empty ( $tpl ) ? trailingslashit ( $tpl ) : '');
	return "BASE_URL.'{$url}'." . $params [0];
}
/**
 * Smarty fire modifier plugin
 *
 * <code>
 * {'hook'|fire}
 * </code>
 *
 *
 * Type: modifier<br>
 * Name: fire<br>
 * Purpose: 调用系统触发器
 *
 * @param Smarty $compiler        	
 * @return string with compiled code
 */
function smarty_modifiercompiler_fire($hook, $compiler) {
	$filter = $hook [0];
	$args = isset ( $hook [1] ) ? $hook [1] : "''";
	$args1 = isset ( $hook [2] ) ? $hook [2] : "''";
	return "apply_filter({$filter},'',{$args},{$args1})";
}
/**
 * Smarty checked modifier plugin
 *
 * <code>
 * {'0'|checked:$value}
 * </code>
 *
 *
 * Type: modifier<br>
 * Name: checked<br>
 * Purpose: 根据值输出checked="checked"
 *
 * @param Smarty $compiler        	
 * @return string with compiled code
 */
function smarty_modifiercompiler_checked($value, $compiler) {
	return "((is_array($value[1]) && in_array($value[0],$value[1]) ) || $value[0] == $value[1])?'checked = \"checked\"' : ''";
}
/**
 * Smarty paging modifier plugin
 *
 * <code>
 * {url|paging:total:limit:paging_arg:num_per_page}
 * </code>
 *
 *
 * Type: modifier<br>
 * Name: paging<br>
 * Purpose: 输出分页
 *
 * @param Smarty $compiler        	
 * @return string with compiled code
 */
function smarty_modifiercompiler_paging($value, $compiler) {
	if (count ( $value ) < 2) {
		trigger_error ( 'error usage of paging', E_USER_WARNING );
		return "'error usage of paging'";
	}
	$url = $value [0]; // url
	$total = $value [1]; // 总数
	if (isset ( $value [2] )) {
		$limit = $value [2]; // 每页显示的条数
	} else {
		$limit = 10; // 默认显示10
	}
	if (isset ( $value [3] )) {
		$param = $value [3]; // 分类参数
	} else {
		$param = "'pid'";
	}
	if (isset ( $value [4] )) {
		$pno = $value [4]; // 分类参数
	} else {
		$pno = 4;
	}
	$output = "paging($total,$limit,null,$param,$pno,$url)";
	return $output;
}
/**
 * Smarty status modifier plugin
 *
 * <code>
 * {value|status:list}
 * </code>
 *
 *
 * Type: modifier<br>
 * Name: status<br>
 * Purpose: 将值做为LIST中的KEY输出LIST对应的值
 *
 * @param Smarty $compiler        	
 * @return string with compiled code
 */
function smarty_modifiercompiler_status($status, $compiler) {
	if (count ( $status ) < 2) {
		trigger_error ( 'error usage of status', E_USER_WARNING );
		return "'error usage of status'";
	}
	$key = "$status[0]";
	$status_str = "$status[1]";
	$output = "$status_str" . "[$key]";
	return $output;
}
/**
 * Smarty sorth modifier plugin
 *
 * <code>
 * {text|sorth:field:[a|d]}
 * </code>
 *
 *
 * Type: modifier<br>
 * Name: sorth<br>
 * Purpose: 生成排序头
 *
 * @param Smarty $compiler        	
 * @return string with compiled code
 */
function smarty_modifiercompiler_sorth($sorth, $compiler) {
	if (count ( $sorth ) < 3) {
		trigger_error ( 'error usage of sorth', E_USER_WARNING );
		return "'error usage of sorth'";
	}
	$text = $sorth [0];
	$field = $sorth [1];
	$url = $sorth [2];
	if (isset ( $sorth [3] )) {
		$dir = $sorth [3];
	} else {
		$dir = "'d'";
	}
	$output = "sortheader($text,$url,$field,$dir)";
	return $output;
}

/**
 * Smarty thumb modifier plugin
 *
 * <code>
 * {original|thumb:[x|y]}
 * </code>
 *
 *
 * Type: modifier<br>
 * Name: sorth<br>
 * Purpose: 生成排序头
 *
 * @param Smarty $compiler        	
 * @return string with compiled code
 */
function smarty_modifiercompiler_thumb($thumb, $compiler) {
	if (count ( $thumb ) < 2) {
		trigger_error ( 'error usage of thumb', E_USER_WARNING );
		return "'error usage of thumb'";
	}
	$url = $thumb [0];
	$w = intval ( $thumb [1] );
	$h = isset ( $thumb [2] ) ? intval ( $thumb [2] ) : $w;
	$output = "the_thumbnail_src($url,$w,$h)";
	return $output;
}
function smarty_modifiercompiler_random($ary, $compiler) {
	if (count ( $ary ) < 1) {
		trigger_error ( 'error usage of random', E_USER_WARNING );
		return "'error usage of random'";
	}
	$output = "is_array({$ary[0]})?{$ary[0]}[array_rand({$ary[0]})]:''";
	return $output;
}

function smarty_modifiercompiler_params($ary, $compiler) {
	if (count ( $ary ) < 1) {
		trigger_error ( 'error usage of params', E_USER_WARNING );
		return "'error usage of params'";
	}
	$url = array_shift ( $ary );
	$args = empty ( $ary ) ? array () : smarty_argstr ( $ary );
	$output = "build_page_url($url,$args)";
	return $output;
}